﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EffectScript : MonoBehaviour {
    public EffectData fromData;
    public EffectData toData;
    public SpriteRenderer mainSprite;

    public float timeToAnimation = 1f;
    public bool destroyOnDone = true;
    public Space space = Space.World;

	System.Action onComplete;
    float elapsed;
    bool isActive;

    public void Awake()
    {
        fromData = new EffectData();
        toData = new EffectData();
    }
    public virtual EffectScript SetSprite(Sprite s)
    {
        mainSprite.sprite = s;
        return this;
    }
    public virtual EffectScript SetTime(float time)
    {
        timeToAnimation = time;
        return this;
    }
    public virtual EffectScript SetOnComplete(System.Action comp)
    {
        onComplete = comp;
        return this;
    }
    public virtual EffectScript SetSpace(Space s)
    {
        space = s;
        return this;
    }
    public virtual EffectScript SetDestroyOnDone(bool destroy)
    {
        destroyOnDone = destroy;
        return this;
    }


    public void Reset()
    {
        elapsed = 0;
        onComplete = null;

        if (fromData == null)
            fromData = new EffectData();
        fromData.Init(null);

        if (toData == null)
            toData = new EffectData();
        toData.Init(null);
    }
    public virtual void Init()
    {
        transform.position = fromData.position;
        transform.eulerAngles = fromData.rotate * Vector3.forward;
        transform.localScale = fromData.scale;

		if (mainSprite) {
			mainSprite.SetAlpha (fromData.alpha);
		}
        isActive = true;
    }

    public virtual void Run(EffectData from, EffectData to)
    {
        Reset();
        fromData.Init(from);
        toData.Init(to);

        Init();
    }
    public virtual void RunPosition(Vector3 fromPos, Vector3 toPos)
    {
        Reset();
        
        fromData.position = fromPos;
        toData.position = toPos;

        Init();
    }
    public virtual void RunRotate(Vector3 pos, float fromRot, float toRot)
    {
        Reset();

        fromData.position = pos;
        toData.position = pos;
        fromData.rotate = fromRot;
        toData.rotate = toRot;

        Init();
    }
    public virtual void RunScale(Vector3 pos, Vector3 fromScale, Vector3 toScale)
    {
        Reset();

        fromData.position = pos;
        toData.position = pos;
        fromData.scale = fromScale;
        toData.scale = toScale;

        Init();
    }
    public virtual void RunAlpha(Vector3 pos, float fromAlpha, float toAlpha)
    {
        Reset();

        fromData.position = pos;
        toData.position = pos;
        fromData.alpha = fromAlpha;
        toData.alpha = toAlpha;

        Init();
    }
	private void OnEffectComplete ()
	{
		UiManager.SetCoinText (true,1);
	}
    private void Update()
    {
        if (!isActive)
            return;
        if(elapsed >= timeToAnimation)
        {
            isActive = false;
			OnEffectComplete ();
            if (onComplete != null)
                onComplete.Invoke();

            if (destroyOnDone)
                gameObject.Recycle();
        }

        float delta = elapsed / timeToAnimation;

        if (fromData.position != toData.position)
            UpdatePosition(delta);

        if (fromData.rotate != toData.rotate)
            UpdateRotate(delta);

        if (fromData.scale != toData.scale)
            UpdateScale(delta);

        if (fromData.alpha != toData.alpha)
            UpdateAlpha(delta);

        elapsed += Time.deltaTime;
    }

    public virtual void UpdatePosition(float delta)
    {
        if (space == Space.World)
        {
            transform.position = Vector3.Lerp(fromData.position, toData.position, delta);
        }
        else
        {
            transform.localPosition = Vector3.Lerp(fromData.position, toData.position, delta);
        }
    }

    public virtual void UpdateRotate(float delta)
    {
        if (space == Space.World)
        {
            transform.eulerAngles = Vector3.forward * Mathf.Lerp(fromData.rotate, toData.rotate, delta);
        }
        else
        {
            transform.localEulerAngles = Vector3.forward * Mathf.Lerp(fromData.rotate, toData.rotate, delta);
        }
    }

    public virtual void UpdateScale(float delta)
    {
        transform.localScale = Vector3.Lerp(fromData.scale, toData.scale, delta);
    }
    public virtual void UpdateAlpha(float delta)
    {
        if(mainSprite)
            mainSprite.SetAlpha(Mathf.Lerp(fromData.alpha, toData.alpha, delta));
    }
}

[System.Serializable]
public class EffectData
{
    public Vector3 position;
    public float rotate;
    public Vector3 scale;
    public float alpha;

    public EffectData()
    {
        position = Vector3.zero;
        rotate = 0;
        scale = Vector3.one;
        alpha = 1;
    }
    public void Init(EffectData e)
    {
        if (e == null)
        {
            position = Vector3.zero;
            rotate = 0;
            scale = Vector3.one;
            alpha = 1;
        }
        else
        {
            position = e.position;
            rotate = e.rotate;
            scale = e.scale;
            alpha = e.alpha;
        }
    }
}
